#include <iostream>
#include "matrix.h"

using namespace std;

void testMatrix(){
	mcmcMatrix<int> nMat();
	mcmcMatrix<int> mat1(3, 5);
	mat1.Set(1);
	cout << mat1 << endl;
	mat1 = mat1 + (-2.5);
	cout << mat1 << endl;

	cout << "Testing + - * / with numbers" << endl;
	mat1 = mat1 - 1;
	mcmcMatrix<int> mat2(mat1);
	mat2 = mat2 * 2;
	cout << mat2 << endl;
	mat2 = mat2 / 5;
	cout << mat2 << endl;
	mat1(1, 2) = 3;
	cout << "Mat1:" << endl << mat1 << "Mat2:" << endl << mat2 << endl;
	mcmcMatrix<int> mat3 = mat1^mat2;
	cout << mat3 << endl;

	cout << "Testing + - * with matrices" << endl;
	cout << "Mat1:" << endl << mat1 << "Mat2:" << endl << mat2 << endl;
	cout << "Mat1 + Mat2: " << endl << mat1 + mat2 << endl;
	cout << "Mat1 - Mat2: " << endl << mat1 - mat2 << endl;
	mat3.SetDimension(5, 3);
	mat3.Set(3);
	cout << "Mat3:" << endl << mat3 << endl;
	cout << "Mat1 * Mat3" << endl << mat1*mat3 << endl;
	cout << mat1(1, 2) << " " << mat1(7) << endl;
	mat3.ExpandTo(6, 4);
	cout << mat3 << endl;
	int nRow, nCol;
	mat3.GetDimension(nRow, nCol);
	cout << nRow << " " << nCol << endl;
	cout << mat3.rows() << " " << mat3.cols() << " " << mat3.size() << " " << mat3.nx() << " " << mat3.ny() << endl;
	cout << mat3.Valid(0, 0) << " " << mat3.Valid(-1, 0) << " " << mat3.Valid(5) << " " << mat3.Valid(5, 6) << " " << mat3.Valid(5, 3) << " " << endl;
	
	mat3.SetDimension(3, 4);
	mat3.InitValue(1);
	cout << mat3.T() << endl;
	mat3.SetDimension(3, 3);
	mat3.Identity();
	cout << "Mat3:" << endl << mat3 << endl;
	cout << "Det of Mat3:" << endl << mat3.Det() << endl;
	mat3.Zero();
	cout << "Mat3:" << endl << mat3 << endl;
	cout << "Det of Mat3:" << endl << mat3.Det() << endl;
	cout << "NoZeroDet of Mat3:" << endl << mat3.DetNoZero() << endl;

	cout << "Testing inverse of matrices.." << endl;
	mcmcMatrix<double> mat4(3, 3);
	mat4(0) = 1;
	mat4(1) = 3;
	mat4(2) = 4;
	mat4(3) = 2;
	mat4(4) = 5;
	mat4(5) = 8;
	mat4(6) = 9;
	mat4(7) = 7;
	mat4(8) = 6;
	cout << "Mat4:" << endl << mat4 << endl;
	cout << "Inverse:" << endl << mat4.Inv() << endl;
	cout << mat4.Data(1, 2) << " " << mat4.Data(5) << endl;

	cout << "Testing functionalities" << endl;
	double foo1, foo2;
	mat4.GetMinMax(foo1, foo2);
	cout << mat4.GetMax() << " " << mat4.GetMin() << " " << foo1 << " " << foo2 << endl;
	cout << mat4.Sum() << " " << mat4.SumL2() << endl;
	cout << mat4.Mean() << endl << mat4.Inv().mabs() << endl;

	cout << "Testing Eigen" << endl;
	mcmcMatrix<double> eigenvalues, eigenvectors;
	mat4.Eigen(eigenvalues, eigenvectors);
	cout << "Mat4: " << endl << mat4 << endl;
	cout << eigenvalues << endl << eigenvectors << endl;
}

void testMatrix1(){
	mcmcMatrix<unsigned int> mat;
	mat.SetDimension(5, 4);
	cout << mat.data.type() << " " << CV_8UC1 << endl;
	mat.InitValue(0);
}

int main(){
	//testMatrix();
	testMatrix1();

	system("pause");
	return 0;
}